{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 导入相关包&构造数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x29c7edf6340>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# ⾸先导⼊⼀些包，来模拟出⼀些数据\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import random\n",
    "from sklearn.datasets import make_blobs\n",
    "\n",
    "sample_size = 200\n",
    "centers = [[1,1], [3,4]]\n",
    "X, Y = make_blobs(n_samples = sample_size, centers = centers,\n",
    "cluster_std = 0.6, random_state = 11) \n",
    "Y[Y == 0] = -1\n",
    "plt.scatter(X[:,0], X[:,1], cmap = 'cool', c = Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 离最优的超平面的点，越麻烦\n",
    "2. 最优的超平面就是在尝试在这些麻烦的点的位置，不断的利用他们的信息调整超平面的位置\n",
    "3. 这些点被更新的次数越大，以为着ai的次数越大\n",
    "4. ai越大，从对偶公式上可以看到，w,b的值绝大部分都是通过这些麻烦的点得到的\n",
    "5. 最优超平面的位置就是由这些麻烦的点来确定的\n",
    "6. 其他的点，相对超平面较远，这些ai的值甚至为0，不会参与最后的w，b的运算"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 设置初始的w、b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "w = np.array([1]*X.shape[1])\n",
    "b = 1\n",
    "lam = 0.1 #步长"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1, 1]), 1)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w,b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 单样本梯度下降"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "count = 0 \n",
    "while True:\n",
    "    count += 1 \n",
    "    # missing_index 记录误分类点的索引--拿到样本信息做梯度更新\n",
    "    missing_index = -1 \n",
    "    for i in range(X.shape[0]):\n",
    "        # y_i * (w*x_i+b) < 0 \n",
    "        checking = Y[i] * (np.dot(w,X[i]) + b)\n",
    "        if checking<0:\n",
    "            missing_index = i #将误分类点记录\n",
    "            break\n",
    "             \n",
    "    # 直到没有误分类点-结束循环\n",
    "    if missing_index == -1:\n",
    "        break\n",
    "        \n",
    "    #更新w、b\n",
    "    w = w + lam * Y[missing_index] * X[missing_index]\n",
    "    b = b + lam * Y[missing_index]        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([0.08179182, 0.29270092]), -0.8999999999999998, 32)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w,b,count"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "问题： 会不会发生死循环?\n",
    "答案： 如果数据集是线性可分的，肯定会跳出循环的，这是可以通过数据公式证明的---感知机算法是可收敛的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- SVM是有参数模型还是无参模型？（面试题）\n",
    "感知机与SVM一样，有原始的模型，也有转换后的对偶模型\n",
    "对偶模型会分配到一个ai，在原始的模型参数个数是有限的，\n",
    "转换成对偶形态就是无限参数了，也就是无参模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 使用sklean中的多层感知机进行手写数字的识别"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 导入相关包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neural_network import MLPClassifier #多层感知机模型\n",
    "from tensorflow.keras.datasets import mnist #手写数字的数据集   #TF2.x \n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据&处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "(Xtrain,Ytrain),(Xtest,Ytest) = mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(60000, 28, 28)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xtrain.shape # (28,28,1)  #像素大小28*28   取值范围0-255之间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Ytrain[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 观测图片数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(28, 28)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xtrain[0].shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAAAAABXZoBIAAABAElEQVR4nGNgGMyAWUhIqK5jvdSy/9/rGRgYGFhgEnJsVjYCwQwMDAxPJgV+vniQgYGBgREqZ7iXH8r6l/SV4dn7m8gmCt3++/fv37/Htn3/iMW+gDnZf/+e5WbQnoXNNXyMs/5GoQoxwVmf/n9kSGFiwAW49/11wynJoPzx4YIcRlyygR/+/i2XxCWru+vv32nSuGQFYv/83Y3b4p9/fzpAmSyoMnohpiwM1w5h06Q+5enfv39/bcMiJVF09+/fv39P+mFKiTtd/fv3799jgZiBJLT69t+/f/8eDuDEkDJf8+jv379/v7Ryo4qzMDAwMAQGMjBc3/y35wM2V1IfAABFF16Aa0wAOwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<PIL.Image.Image image mode=L size=28x28 at 0x29C0A4940A0>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Image.fromarray(Xtrain[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(255, 0)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xtrain.max(),Xtrain.min() # 0-255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 归一化  压缩到0-1之间 \n",
    "Xtrain = (Xtrain-Xtrain.min())/(Xtrain.max()-Xtrain.min())\n",
    "Xtest = (Xtest-Xtest.min())/(Xtest.max()-Xtest.min())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.01176471, 0.07058824, 0.07058824,\n",
       "        0.07058824, 0.49411765, 0.53333333, 0.68627451, 0.10196078,\n",
       "        0.65098039, 1.        , 0.96862745, 0.49803922, 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.11764706, 0.14117647,\n",
       "        0.36862745, 0.60392157, 0.66666667, 0.99215686, 0.99215686,\n",
       "        0.99215686, 0.99215686, 0.99215686, 0.88235294, 0.6745098 ,\n",
       "        0.99215686, 0.94901961, 0.76470588, 0.25098039, 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.19215686, 0.93333333, 0.99215686,\n",
       "        0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686,\n",
       "        0.99215686, 0.99215686, 0.98431373, 0.36470588, 0.32156863,\n",
       "        0.32156863, 0.21960784, 0.15294118, 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.07058824, 0.85882353, 0.99215686,\n",
       "        0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.77647059,\n",
       "        0.71372549, 0.96862745, 0.94509804, 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.31372549, 0.61176471,\n",
       "        0.41960784, 0.99215686, 0.99215686, 0.80392157, 0.04313725,\n",
       "        0.        , 0.16862745, 0.60392157, 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.05490196,\n",
       "        0.00392157, 0.60392157, 0.99215686, 0.35294118, 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.54509804, 0.99215686, 0.74509804, 0.00784314,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.04313725, 0.74509804, 0.99215686, 0.2745098 ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.1372549 , 0.94509804, 0.88235294,\n",
       "        0.62745098, 0.42352941, 0.00392157, 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.31764706, 0.94117647,\n",
       "        0.99215686, 0.99215686, 0.46666667, 0.09803922, 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.17647059,\n",
       "        0.72941176, 0.99215686, 0.99215686, 0.58823529, 0.10588235,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.0627451 , 0.36470588, 0.98823529, 0.99215686, 0.73333333,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.97647059, 0.99215686, 0.97647059,\n",
       "        0.25098039, 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.18039216,\n",
       "        0.50980392, 0.71764706, 0.99215686, 0.99215686, 0.81176471,\n",
       "        0.00784314, 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.15294118, 0.58039216, 0.89803922,\n",
       "        0.99215686, 0.99215686, 0.99215686, 0.98039216, 0.71372549,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.09411765, 0.44705882, 0.86666667, 0.99215686, 0.99215686,\n",
       "        0.99215686, 0.99215686, 0.78823529, 0.30588235, 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.09019608, 0.25882353,\n",
       "        0.83529412, 0.99215686, 0.99215686, 0.99215686, 0.99215686,\n",
       "        0.77647059, 0.31764706, 0.00784314, 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.07058824, 0.67058824, 0.85882353, 0.99215686,\n",
       "        0.99215686, 0.99215686, 0.99215686, 0.76470588, 0.31372549,\n",
       "        0.03529412, 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.21568627,\n",
       "        0.6745098 , 0.88627451, 0.99215686, 0.99215686, 0.99215686,\n",
       "        0.99215686, 0.95686275, 0.52156863, 0.04313725, 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.53333333,\n",
       "        0.99215686, 0.99215686, 0.99215686, 0.83137255, 0.52941176,\n",
       "        0.51764706, 0.0627451 , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ],\n",
       "       [0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "        0.        , 0.        , 0.        ]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xtrain[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将特征展开---压缩成1维\n",
    "Xtrain = Xtrain.reshape((60000,28*28))\n",
    "Xtest = Xtest.reshape((10000,28*28))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.01176471, 0.07058824, 0.07058824,\n",
       "       0.07058824, 0.49411765, 0.53333333, 0.68627451, 0.10196078,\n",
       "       0.65098039, 1.        , 0.96862745, 0.49803922, 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.11764706, 0.14117647, 0.36862745, 0.60392157,\n",
       "       0.66666667, 0.99215686, 0.99215686, 0.99215686, 0.99215686,\n",
       "       0.99215686, 0.88235294, 0.6745098 , 0.99215686, 0.94901961,\n",
       "       0.76470588, 0.25098039, 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.19215686, 0.93333333,\n",
       "       0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686,\n",
       "       0.99215686, 0.99215686, 0.99215686, 0.98431373, 0.36470588,\n",
       "       0.32156863, 0.32156863, 0.21960784, 0.15294118, 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.07058824, 0.85882353, 0.99215686, 0.99215686,\n",
       "       0.99215686, 0.99215686, 0.99215686, 0.77647059, 0.71372549,\n",
       "       0.96862745, 0.94509804, 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.31372549, 0.61176471, 0.41960784, 0.99215686, 0.99215686,\n",
       "       0.80392157, 0.04313725, 0.        , 0.16862745, 0.60392157,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.05490196,\n",
       "       0.00392157, 0.60392157, 0.99215686, 0.35294118, 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.54509804,\n",
       "       0.99215686, 0.74509804, 0.00784314, 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.04313725, 0.74509804, 0.99215686,\n",
       "       0.2745098 , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.1372549 , 0.94509804, 0.88235294, 0.62745098,\n",
       "       0.42352941, 0.00392157, 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.31764706, 0.94117647, 0.99215686, 0.99215686, 0.46666667,\n",
       "       0.09803922, 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.17647059,\n",
       "       0.72941176, 0.99215686, 0.99215686, 0.58823529, 0.10588235,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.0627451 , 0.36470588,\n",
       "       0.98823529, 0.99215686, 0.73333333, 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.97647059, 0.99215686,\n",
       "       0.97647059, 0.25098039, 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.18039216, 0.50980392,\n",
       "       0.71764706, 0.99215686, 0.99215686, 0.81176471, 0.00784314,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.15294118,\n",
       "       0.58039216, 0.89803922, 0.99215686, 0.99215686, 0.99215686,\n",
       "       0.98039216, 0.71372549, 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.09411765, 0.44705882, 0.86666667, 0.99215686, 0.99215686,\n",
       "       0.99215686, 0.99215686, 0.78823529, 0.30588235, 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.09019608, 0.25882353, 0.83529412, 0.99215686,\n",
       "       0.99215686, 0.99215686, 0.99215686, 0.77647059, 0.31764706,\n",
       "       0.00784314, 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.07058824, 0.67058824, 0.85882353,\n",
       "       0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.76470588,\n",
       "       0.31372549, 0.03529412, 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.21568627, 0.6745098 ,\n",
       "       0.88627451, 0.99215686, 0.99215686, 0.99215686, 0.99215686,\n",
       "       0.95686275, 0.52156863, 0.04313725, 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.53333333, 0.99215686, 0.99215686, 0.99215686,\n",
       "       0.83137255, 0.52941176, 0.51764706, 0.0627451 , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
       "       0.        , 0.        , 0.        , 0.        ])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Xtrain[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 独热编码--标签\n",
    "Ytrain = np.eye(len(set(Ytrain)))[Ytrain]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "Ytest = np.eye(len(set(Ytest)))[Ytest]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Ytrain[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 建模&训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlp = MLPClassifier(hidden_layer_sizes=(100,),#第一个神经元的个数\n",
    "              activation='logistic',#‘logistic’，‘tanh’，‘relu’}\n",
    "              solver='sgd',#adam  lbfgs\n",
    "              alpha=0.0001,#L2正则化的参数\n",
    "              batch_size=64,# 一组64个\n",
    "              learning_rate='constant',#用于权重更新---sgd\n",
    "              learning_rate_init=0.1, #初始学习率\n",
    "              max_iter=10000,#最大迭代次数\n",
    "              random_state= 260,#随机种子\n",
    "              verbose=2, #打印训练信息\n",
    "              tol=0.0001 #损失变化<0.0001停止训练\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration 1, loss = 0.68872254\n",
      "Iteration 2, loss = 0.33839330\n",
      "Iteration 3, loss = 0.25732423\n",
      "Iteration 4, loss = 0.21377680\n",
      "Iteration 5, loss = 0.18156845\n",
      "Iteration 6, loss = 0.15896962\n",
      "Iteration 7, loss = 0.14178300\n",
      "Iteration 8, loss = 0.12809906\n",
      "Iteration 9, loss = 0.11671533\n",
      "Iteration 10, loss = 0.10587440\n",
      "Iteration 11, loss = 0.09774907\n",
      "Iteration 12, loss = 0.08912762\n",
      "Iteration 13, loss = 0.08288436\n",
      "Iteration 14, loss = 0.07668282\n",
      "Iteration 15, loss = 0.07023785\n",
      "Iteration 16, loss = 0.06601220\n",
      "Iteration 17, loss = 0.06126660\n",
      "Iteration 18, loss = 0.05809800\n",
      "Iteration 19, loss = 0.05415096\n",
      "Iteration 20, loss = 0.05051269\n",
      "Iteration 21, loss = 0.04734493\n",
      "Iteration 22, loss = 0.04465057\n",
      "Iteration 23, loss = 0.04190426\n",
      "Iteration 24, loss = 0.03985653\n",
      "Iteration 25, loss = 0.03764381\n",
      "Iteration 26, loss = 0.03587037\n",
      "Iteration 27, loss = 0.03420921\n",
      "Iteration 28, loss = 0.03255064\n",
      "Iteration 29, loss = 0.03090571\n",
      "Iteration 30, loss = 0.02956673\n",
      "Iteration 31, loss = 0.02845669\n",
      "Iteration 32, loss = 0.02715331\n",
      "Iteration 33, loss = 0.02612693\n",
      "Iteration 34, loss = 0.02535290\n",
      "Iteration 35, loss = 0.02440051\n",
      "Iteration 36, loss = 0.02352913\n",
      "Iteration 37, loss = 0.02288018\n",
      "Iteration 38, loss = 0.02222031\n",
      "Iteration 39, loss = 0.02156305\n",
      "Iteration 40, loss = 0.02103953\n",
      "Iteration 41, loss = 0.02043297\n",
      "Iteration 42, loss = 0.02004959\n",
      "Iteration 43, loss = 0.01961485\n",
      "Iteration 44, loss = 0.01919244\n",
      "Iteration 45, loss = 0.01879225\n",
      "Iteration 46, loss = 0.01841834\n",
      "Iteration 47, loss = 0.01804252\n",
      "Iteration 48, loss = 0.01778211\n",
      "Iteration 49, loss = 0.01743749\n",
      "Iteration 50, loss = 0.01712624\n",
      "Iteration 51, loss = 0.01688520\n",
      "Iteration 52, loss = 0.01665329\n",
      "Iteration 53, loss = 0.01646974\n",
      "Iteration 54, loss = 0.01625678\n",
      "Iteration 55, loss = 0.01606665\n",
      "Iteration 56, loss = 0.01587022\n",
      "Iteration 57, loss = 0.01566388\n",
      "Iteration 58, loss = 0.01556517\n",
      "Iteration 59, loss = 0.01536372\n",
      "Iteration 60, loss = 0.01524216\n",
      "Iteration 61, loss = 0.01507154\n",
      "Iteration 62, loss = 0.01500246\n",
      "Iteration 63, loss = 0.01485462\n",
      "Iteration 64, loss = 0.01471479\n",
      "Iteration 65, loss = 0.01456288\n",
      "Iteration 66, loss = 0.01449353\n",
      "Iteration 67, loss = 0.01438505\n",
      "Iteration 68, loss = 0.01427661\n",
      "Iteration 69, loss = 0.01417840\n",
      "Iteration 70, loss = 0.01407893\n",
      "Iteration 71, loss = 0.01403421\n",
      "Iteration 72, loss = 0.01393912\n",
      "Iteration 73, loss = 0.01387761\n",
      "Iteration 74, loss = 0.01379174\n",
      "Iteration 75, loss = 0.01368175\n",
      "Iteration 76, loss = 0.01363840\n",
      "Iteration 77, loss = 0.01355976\n",
      "Iteration 78, loss = 0.01351671\n",
      "Iteration 79, loss = 0.01345078\n",
      "Iteration 80, loss = 0.01340208\n",
      "Iteration 81, loss = 0.01334709\n",
      "Iteration 82, loss = 0.01331221\n",
      "Iteration 83, loss = 0.01324523\n",
      "Iteration 84, loss = 0.01319200\n",
      "Iteration 85, loss = 0.01316060\n",
      "Iteration 86, loss = 0.01311530\n",
      "Training loss did not improve more than tol=0.000100 for 10 consecutive epochs. Stopping.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "MLPClassifier(activation='logistic', batch_size=64, learning_rate_init=0.1,\n",
       "              max_iter=10000, random_state=260, solver='sgd', verbose=2)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 训练模型\n",
    "mlp.fit(Xtrain,Ytrain)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mlp.score(Xtrain,Ytrain)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9613"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mlp.score(Xtest,Ytest)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SVM实现手写数字的识别"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 导入相关包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import numpy as np\n",
    "from tensorflow.keras.datasets import mnist\n",
    "from sklearn import svm\n",
    "from sklearn.metrics import accuracy_score,confusion_matrix,classification_report"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "(x_train,y_train),(x_test,y_test) = mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# reshape 转成1维向量 28*28 = 784 \n",
    "x_train = x_train.reshape(60000,784).astype('float32')\n",
    "x_test = x_test.reshape(10000,784).astype('float32')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据归一化\n",
    "x_train = x_train / 255\n",
    "x_test = x_test / 255"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1.gamma  核函数系数，只对‘rbf’,'poly','sigmod'有效\n",
    "# 2.C  错误项的惩罚系数。C越大，对分错样本的惩罚程度越大\n",
    "#  C 越小，容许训练集中有一些误分类的样本，泛化能力越强。\n",
    "# 3. kernel =  'rbf'\n",
    "clf = svm.SVC(C=100.0,kernel='rbf',gamma=0.02)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "t1 = time.time()\n",
    "clf.fit(x_train[:10000],y_train[:10000])\n",
    "t2 = time.time()\n",
    "svm_time = float(t2-t1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型训练的时间：45.3314254283905\n"
     ]
    }
   ],
   "source": [
    "print('模型训练的时间：{}'.format(svm_time))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.97      0.99      0.98       980\n",
      "           1       0.98      0.99      0.99      1135\n",
      "           2       0.96      0.97      0.97      1032\n",
      "           3       0.96      0.96      0.96      1010\n",
      "           4       0.96      0.98      0.97       982\n",
      "           5       0.97      0.96      0.96       892\n",
      "           6       0.97      0.98      0.98       958\n",
      "           7       0.97      0.95      0.96      1028\n",
      "           8       0.97      0.97      0.97       974\n",
      "           9       0.97      0.94      0.96      1009\n",
      "\n",
      "    accuracy                           0.97     10000\n",
      "   macro avg       0.97      0.97      0.97     10000\n",
      "weighted avg       0.97      0.97      0.97     10000\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#得到预测结果\n",
    "predictions = [int(a) for a in clf.predict(x_test)]\n",
    "print(classification_report(y_test,np.array(predictions)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9696"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算准确率\n",
    "accuracy_score(y_test,predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用网格搜索对参数调优"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 设置超参数\n",
    "C = [0.1,0.2,0.5,0.8,1]\n",
    "kernel='rbf'\n",
    "gamma = [0.001,0.01,0.03,0.1,0.5,1]\n",
    "\n",
    "# 构建参数字典\n",
    "param_dict = {\n",
    "    'C':C,\n",
    "    'gamma':gamma\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建SVC实例\n",
    "svc = svm.SVC()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 网格参数搜索\n",
    "gsCV = GridSearchCV(estimator=svc,\n",
    "                    param_grid=param_dict,\n",
    "                    n_jobs=2,\n",
    "                    scoring='r2',cv=6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=6, estimator=SVC(), n_jobs=2,\n",
       "             param_grid={'C': [0.1, 0.2, 0.5, 0.8, 1],\n",
       "                         'gamma': [0.001, 0.01, 0.03, 0.1, 0.5, 1]},\n",
       "             scoring='r2')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gsCV.fit(x_train[:1000],y_train[:1000])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.795276988268982"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最佳得分\n",
    "gsCV.best_score_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'C': 0.8, 'gamma': 0.03}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最优参数\n",
    "gsCV.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC(C=0.8, gamma=0.03)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最优模型\n",
    "gsCV.best_estimator_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用最佳的参数实例化模型\n",
    "svc = svm.SVC(C=gsCV.best_params_['C'],kernel=kernel,gamma=gsCV.best_params_['gamma'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC(C=0.8, gamma=0.03)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "svc.fit(x_train[:1000],y_train[:1000])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "svc_predict = svc.predict(x_test)\n",
    "svc_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "svc_metric = classification_report(y_test,svc_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.94      0.97      0.95       980\n",
      "           1       0.98      0.98      0.98      1135\n",
      "           2       0.85      0.93      0.88      1032\n",
      "           3       0.95      0.83      0.89      1010\n",
      "           4       0.87      0.92      0.89       982\n",
      "           5       0.82      0.92      0.87       892\n",
      "           6       0.96      0.88      0.92       958\n",
      "           7       0.93      0.92      0.92      1028\n",
      "           8       0.93      0.83      0.87       974\n",
      "           9       0.87      0.88      0.88      1009\n",
      "\n",
      "    accuracy                           0.91     10000\n",
      "   macro avg       0.91      0.91      0.91     10000\n",
      "weighted avg       0.91      0.91      0.91     10000\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(svc_metric)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9067"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "accuracy_score(y_test,svc_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "307.2px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
